package com.boss.thirteen.service.impl;

import com.boss.common.entity.PageDTO;
import com.boss.framework.dto.PaginationDTO;
import com.boss.salary.constant.SystemDictConstant;
import com.boss.salary.entity.SalaryPaymentRequisitionBack;
import com.boss.salary.service.IRedisService;
import com.boss.sys.ca.user.dto.UserDTO;
import com.boss.thirteen.dao.ISalaryThirteenMonthDao;
import com.boss.thirteen.dao.ISalaryThirteenMouldDao;
import com.boss.thirteen.dao.IThirteenAgencyVerifyDao;
import com.boss.thirteen.dao.IThirteenPaymentBackDao;
import com.boss.thirteen.entity.SalaryThirteenMonth;
import com.boss.thirteen.entity.ThirteenAgencyVerify;
import com.boss.thirteen.service.IThirteenSalaryEndAsyncService;
import com.boss.thirteen.service.IThirteenSalaryEndService;
import com.singularsys.jep.JepException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@EnableAsync
public class ThirteenSalaryEndServiceImpl implements IThirteenSalaryEndService {
    /**
     * 引入日志框架常量
     */
    private static final Logger logger = LoggerFactory.getLogger(ThirteenSalaryEndServiceImpl.class);
    private static final String COLUMN_PREFIX = "getS";

    private static DateFormat df = new SimpleDateFormat("yyyy-MM");

    private Class<? extends Object> clazz = null;
    private Method[] methods = null;




    @Autowired
    private ISalaryThirteenMonthDao salaryThirteenMonthDao;
    @Autowired
    private IThirteenAgencyVerifyDao thirteenAgencyVerifyDao;
    @Autowired
    private IRedisService redisService;
    @Autowired
    private IThirteenSalaryEndAsyncService SalaryHistoryAsyncService;
    @Autowired
    private ISalaryThirteenMouldDao salaryThirteenMouldDao;
    @Autowired
    private IThirteenPaymentBackDao thirteenPaymentBackDao;


    @Override
    public Map<String,String> saveMonthEnd( String province, List<ThirteenAgencyVerify> agencyVerifyLists) throws InvocationTargetException, IllegalAccessException, ParseException, NoSuchMethodException, JepException {
        logger.info("----------------十三月结Begin---------------------");
        //单位id集合
        List<String> agencyIds = new ArrayList<>();
        // 获取单位审核表中当前月份
        List<String> monthEndAgencyIds = new ArrayList<>();
        Map<String,String> requestMap=new HashMap<>();
        for(ThirteenAgencyVerify agencyVerify:agencyVerifyLists){
            monthEndAgencyIds.add(agencyVerify.getAgencyId());
        }
        List<ThirteenAgencyVerify> agencyVerifyList = thirteenAgencyVerifyDao.getAgencyVerifyByAgencyIds(monthEndAgencyIds);
        if (agencyVerifyLists.size() > 0) {
            // 1-12 月份每个单位对应的月份集合
            Map<String, String> yearMap = agencyVerifyList.stream().collect(Collectors.toMap(ThirteenAgencyVerify::getAgencyId,ThirteenAgencyVerify::getYear));
            Map<String, String> agencyNameMap = agencyVerifyList.stream().collect(Collectors.toMap(ThirteenAgencyVerify::getAgencyId,ThirteenAgencyVerify::getAgencyName));
            Map<String, String> agencyCodeMap = agencyVerifyList.stream().collect(Collectors.toMap(ThirteenAgencyVerify::getAgencyId,ThirteenAgencyVerify::getAgencyCode));
            agencyIds=agencyVerifyList.stream().map(ThirteenAgencyVerify::getAgencyId).collect(Collectors.toList());
            // 根据单位审核状态表，获取每个单位当前未月结的月份
            String uuid="2021-"+province+"-thirteenLunarKnot";
            logger.info("十三月结进度:"+uuid);
            redisService.put(uuid, 0);
            requestMap.put("guid",uuid);
            if (agencyIds.size() > 0) {
                SalaryHistoryAsyncService.saveMonthEndAsynchronous(province,agencyIds,yearMap,agencyNameMap,agencyCodeMap,uuid);
            }
            logger.info("----------------十三月结End---------------------");



        }

        return  requestMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> checkRevokeMonthEnd(UserDTO userDTO,List<String> agencyIds, String year) {
        Map<String, Object> result = new HashMap<>(2);
        boolean flag = true;
        String message = "";
        String maxYear=salaryThirteenMouldDao.getMaxMouldYear(userDTO.getProvince());
        if(!year.equals(maxYear)){
            flag = false;
            message = "非最新模板年份，不允许撤销十三月结！";
            result.put("flag", flag);
            result.put("message", message);
            return result;
        }

        List<ThirteenAgencyVerify> list = thirteenAgencyVerifyDao.getAgencyVerifyByAgencyIds(agencyIds);
        if (!StringUtils.isEmpty(list) && list.size() > 0) {
                flag = false;
                message = "已生成新年度模板，不允许撤销十三月结！";
                result.put("flag", flag);
                result.put("message", message);
                return result;
        }
        result.put("flag", flag);
        result.put("message", message);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void revokeMonthEnd(String province,List<ThirteenAgencyVerify> agencyVerifyLists) {
        try {
        //批量修改单位审核表的上报状态后，增加下个月的初始数据
        logger.info("==================批量修改审核表数据 Begin ================");
        List<String> agencyIds= agencyVerifyLists.stream().map(ThirteenAgencyVerify::getAgencyId).collect(Collectors.toList());
        thirteenAgencyVerifyDao.updateAgencyVerifyEndStatus(province,agencyIds,agencyVerifyLists.get(0).getYear(), SystemDictConstant.NOT_END);
        logger.info("==================批量修改审核表数据 End ================");

        logger.info("==================批量存储工资表历史表数据 Begin ================");
        // 转换工资表数据并添加到历史表
        List<SalaryThirteenMonth> stms=salaryThirteenMonthDao.selectSalaryThirteenMonthHis(agencyIds,agencyVerifyLists.get(0).getYear());
        salaryThirteenMonthDao.deleteSalaryThirteenMonthHisByAgencys(agencyIds,agencyVerifyLists.get(0).getYear());
        salaryThirteenMonthDao.batchInsertSalaryThirteenMonth(stms);
        logger.info("==================批量存储工资表历史表数据 End ================");

        logger.info("==================批量存储支付回盘数据 Begin ================");
        //支付回盘信息保存到历史表中，同时清空回盘信息
        List<SalaryPaymentRequisitionBack> spList=thirteenPaymentBackDao.getPaymentHisDatas(agencyVerifyLists.get(0).getYear(),agencyIds);
        thirteenPaymentBackDao.deletePaymentHistory(agencyVerifyLists.get(0).getYear(),agencyIds);
        thirteenPaymentBackDao.batchInsertPaymentDatas(spList);
        logger.info("==================批量存储支付回盘数据 End ================");
        salaryThirteenMouldDao.updateSalaryThirteenMouldStatus(agencyVerifyLists.get(0).getMouldKey(),SystemDictConstant.NOT_END,null);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }


    @Override
    public PageDTO<Map<String,Object>> getSalaryMonthEndPage(PaginationDTO paginationDTO, Map<String, Object> queryParam, List<String> childrenIds) {
        List<Map<String,Object>> salary = salaryThirteenMonthDao.selectVerifySalaryData(paginationDTO,null, childrenIds,queryParam);
        int total = salaryThirteenMonthDao.selectVerifySalaryDataTotal(null, childrenIds,queryParam);
        PageDTO<Map<String,Object>> pageDTO = new PageDTO<>();
        pageDTO.setRows(salary);
        pageDTO.setTotal(total);
        return pageDTO;
    }

    @Override
    public PageDTO<Map<String,Object>> getSalaryMonthHistoryPage(PaginationDTO paginationDTO, Map<String, Object> queryParam, List<String> childrenIds) {
        List<Map<String,Object>> salary = salaryThirteenMonthDao.selectVerifySalaryHisData(paginationDTO,"", childrenIds,queryParam);
        int total = salaryThirteenMonthDao.selectVerifySalaryHisDataTotal("", childrenIds,queryParam);
        PageDTO<Map<String,Object>> pageDTO = new PageDTO<>();
        pageDTO.setRows(salary);
        pageDTO.setTotal(total);
        return pageDTO;
    }

}
